import java.text.SimpleDateFormat;
import java.util.*;

class Transaction {
    private Date date;
    private double amount;
    private String category;
    private String note;

    public Transaction(Date date, double amount, String category, String note) {
        this.date = date;
        this.amount = amount;
        this.category = category;
        this.note = note;
    }

    public Date getDate() {
        return date;
    }

    public double getAmount() {
        return amount;
    }

    public String getCategory() {
        return category;
    }

    public String getNote() {
        return note;
    }

    @Override
    public String toString() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return "日期: " + sdf.format(date) + ", 金额: " + amount + ", 类别: " + category + ", 备注: " + note;
    }
}

class PersonalFinanceManager {
    private List<Transaction> transactions;

    public PersonalFinanceManager() {
        transactions = new ArrayList<>();
    }

    public void recordIncome(Date date, double amount, String category, String note) {
        if (amount <= 0) {
            System.out.println("收入金额必须为正数。");
            return;
        }
        transactions.add(new Transaction(date, amount, category, note));
        System.out.println("收入记录成功。");
    }

    public void recordExpense(Date date, double amount, String category, String note) {
        if (amount <= 0) {
            System.out.println("支出金额必须为正数。");
            return;
        }
        transactions.add(new Transaction(date, -amount, category, note));
        System.out.println("支出记录成功。");
    }

    public void queryTransactions() {
        for (Transaction t : transactions) {
            System.out.println(t);
        }
    }

    public void queryTransactionsByCategory(String category) {
        for (Transaction t : transactions) {
            if (t.getCategory().equalsIgnoreCase(category)) {
                System.out.println(t);
            }
        }
    }

    public void queryTransactionsByDateRange(Date startDate, Date endDate) {
        for (Transaction t : transactions) {
            if (t.getDate().compareTo(startDate) >= 0 && t.getDate().compareTo(endDate) <= 0) {
                System.out.println(t);
            }
        }
    }

    public double getTotalIncome() {
        return transactions.stream().filter(t -> t.getAmount() > 0).mapToDouble(Transaction::getAmount).sum();
    }

    public double getTotalExpense() {
        return transactions.stream().filter(t -> t.getAmount() < 0).mapToDouble(Transaction::getAmount).sum();
    }

    public double getNetBalance() {
        return getTotalIncome() + getTotalExpense();
    }
}
